package com.hupu.jrs.ui.content

import android.net.Uri
import android.text.TextUtils
import android.webkit.JavascriptInterface
import com.hupu.jrs.api.forum.ForumApi
import com.hupu.jrs.data.ContentRepository
import com.hupu.jrs.otto.UpdateContentPageEvent
import com.hupu.jrs.provider.LocalImageProvider
import com.hupu.jrs.util.ConfigUtil
import com.hupu.jrs.util.FileUtil
import com.hupu.jrs.util.FormatUtil
import com.hupu.jrs.util.ToastUtil
import java.io.File
import java.util.ArrayList
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import rx.functions.Action1
import rx.schedulers.Schedulers
import rx.subscriptions.CompositeSubscription

/**
 * Created by sll on 2016/5/25.
 */
class ContentPagerPresenter @Inject
constructor(private val mContentRepository: ContentRepository, private val mForumApi: ForumApi, private val mBus: Bus,
            private val mImageCacheDao: ImageCacheDao, private val mOkHttpHelper: OkHttpHelper, private val mUserStorage: UserStorage) : ContentPagerContract.Presenter {

    private var mContentView: ContentPagerContract.View? = null

    private val mCompositeSubscription = CompositeSubscription()

    private val imageMap = ConcurrentHashMap<String, String>()
    private val taskArray = ArrayList<String>()

    private var lightReplies: List<ThreadReply> = ArrayList<ThreadReply>()
    private var replies: List<ThreadReply> = ArrayList<ThreadReply>()
    private var fid: String? = null
    private var tid: String? = null
    private var page: Int = 0

    private val isLogin: Boolean
        get() {
            if (!mUserStorage.isLogin()) {
                ToastUtil.showToast("请先登录!!")
                mContentView!!.showLoginUi()
                return false
            }
            return true
        }

    override val javaScriptInterface: HupuBridge
        get() = HupuBridge()

    override fun onThreadInfoReceive(tid: String?, fid: String?, pid: String, page: Int) {
        this.fid = fid
        this.tid = tid
        this.page = page
        if (page == 1) {
            val mSubscription = mContentRepository.getThreadInfo(fid, tid)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(Action1<Any> { threadInfo ->
                        if (threadInfo.getError() != null) {
                            val error = threadInfo.getError()
                            ToastUtil.showToast(error.text)
                            mContentView!!.onClose()
                        } else {
                            mContentView!!.sendMessageToJS("addThreadInfo", threadInfo)
                            loadLightReplies(tid, fid)
                            loadReplies(tid, fid, page)
                            mContentView!!.hideLoading()
                            mBus.post(
                                    UpdateContentPageEvent(threadInfo.getPage(), threadInfo.getTotalPage()))
                        }
                    }, Action1<Throwable> { throwable ->
                        throwable.printStackTrace()
                        mContentView!!.onError()
                    })
            mCompositeSubscription.add(mSubscription)
        } else {
            loadReplies(tid, fid, page)
        }
    }

    override fun onReply(area: Int, index: Int) {
        if (!isLogin) {
            return
        }
        val reply = if (area == 0) lightReplies[index] else replies[index]
        mContentView!!.showReplyUi(fid, tid, reply.pid, reply.content)
    }

    override fun onReport(area: Int, index: Int) {
        if (!isLogin) {
            return
        }
        val reply = if (area == 0) lightReplies[index] else replies[index]
        mContentView!!.showReportUi(tid, reply.pid)
    }

    override fun addLight(area: Int, index: Int) {
        if (!isLogin) {
            return
        }
        val reply = if (area == 0) lightReplies[index] else replies[index]
        mForumApi.addLight(tid, fid, reply.pid)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(Action1<Any> { baseData ->
                    if (baseData != null) {
                        if (baseData.status === 200) {
                            val light = AddLight(baseData.result, reply.pid)
                            mContentView!!.sendMessageToJS("addLight", light)
                            ToastUtil.showToast("点亮成功")
                        } else if (baseData.error != null) {
                            ToastUtil.showToast(baseData.error.text)
                        }
                    } else {
                        ToastUtil.showToast("点亮失败，请检查网络后重试")
                    }
                }, Action1<Throwable> { ToastUtil.showToast("点亮失败，请检查网络后重试") })
    }

    override fun addRuLight(area: Int, index: Int) {
        if (!isLogin) {
            return
        }
        val reply = if (area == 0) lightReplies[index] else replies[index]
        mForumApi.addRuLight(tid, fid, reply.pid)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(Action1<Any> { baseData ->
                    if (baseData != null) {
                        if (baseData.status === 200) {
                            val light = AddLight(baseData.result, reply.pid)
                            mContentView!!.sendMessageToJS("addLight", light)
                            ToastUtil.showToast("点灭成功")
                        } else if (baseData.error != null) {
                            ToastUtil.showToast(baseData.error.text)
                        }
                    } else {
                        ToastUtil.showToast("点灭失败，请检查网络后重试")
                    }
                }, Action1<Throwable> { ToastUtil.showToast("点灭失败，请检查网络后重试") })
    }

    override fun handlerUrl(url: String) {
        if (!TextUtils.isEmpty(url)) {
            val uri = Uri.parse(url)
            val scheme = uri.scheme
            if (scheme.startsWith("http")) {
                mContentView!!.showBrowserUi(url)
            } else if (scheme.equals("kanqiu", ignoreCase = true)) {
                if (url.contains("topic")) {
                    val tid = uri.lastPathSegment
                    val page = uri.getQueryParameter("page")
                    val pid = uri.getQueryParameter("pid")
                    mContentView!!.showContentUi(tid, pid, if (TextUtils.isEmpty(page)) 1 else Integer.valueOf(page))
                } else if (url.contains("board")) {
                    val boardId = url.substring(url.lastIndexOf("/") + 1)
                    mContentView!!.showThreadListUi(boardId)
                } else if (url.contains("people")) {
                    val uid = url.substring(url.lastIndexOf("/") + 1)
                    mContentView!!.showUserProfileUi(uid)
                }
            }
        }
    }

    override fun onReload() {
        mContentView!!.showLoading()
        onThreadInfoReceive(tid, fid, "", page)
    }

    inner class AddLight(var light: Int, var pid: String)

    private fun loadLightReplies(tid: String?, fid: String?) {
        val mSubscription = mContentRepository.getLightReplies(fid, tid)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(Action1<List<Any>> { threadReplies ->
                    lightReplies = threadReplies
                    if (!threadReplies.isEmpty()) {
                        mContentView!!.sendMessageToJS("addLightTitle", "\"这些回帖亮了\"")
                        for (i in threadReplies.indices) {
                            val reply = threadReplies[i]
                            reply.setIndex(i)
                            mContentView!!.sendMessageToJS("addLightPost", reply)
                        }
                        mContentView!!.loadUrl("javascript:reloadLightStuff();")
                    }
                }, Action1<Throwable> { throwable ->
                    throwable.printStackTrace()
                    mContentView!!.onError()
                })
        mCompositeSubscription.add(mSubscription)
    }

    private fun loadReplies(tid: String?, fid: String?, page: Int) {
        val mSubscription = mContentRepository.getReplies(fid, tid, page)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(Action1<List<Any>> { threadReplies ->
                    replies = threadReplies
                    if (page == 1) {
                        mContentView!!.sendMessageToJS("addReplyTitle", "\"全部回帖\"")
                    }
                    if (threadReplies.isEmpty()) {
                        mContentView!!.loadUrl("javascript:addReplyEmpty();")
                    } else {
                        for (i in threadReplies.indices) {
                            val reply = threadReplies[i]
                            reply.setIndex(i)
                            mContentView!!.sendMessageToJS("addReply", reply)
                        }
                    }
                    mContentView!!.loadUrl("javascript:reloadReplyStuff();")
                    mContentView!!.hideLoading()
                }, Action1<Throwable> { throwable ->
                    throwable.printStackTrace()
                    mContentView!!.onError()
                })
        mCompositeSubscription.add(mSubscription)
    }

    fun attachView(view: ContentPagerContract.View) {
        mContentView = view
        mContentView!!.showLoading()
    }

    fun detachView() {
        if (mCompositeSubscription != null && !mCompositeSubscription.isUnsubscribed) {
            mCompositeSubscription.unsubscribe()
        }
        mContentView = null
    }

    inner class HupuBridge {

        @JavascriptInterface
        fun replaceImage(imageUrl: String, index: Int): String {
            if (imageMap.contains(imageUrl)) {
                return LocalImageProvider.constructUri(imageMap[imageUrl])
            } else {
                val imageCaches = mImageCacheDao.queryBuilder()
                        .where(ImageCacheDao.Properties.Url.eq(imageUrl))
                        .build()
                        .list()
                if (!imageCaches.isEmpty()) {
                    val path = imageCaches.get(0).getPath()
                    if (!TextUtils.isEmpty(path) && FileUtil.exist(path)) {
                        imageMap.put(imageUrl, path)
                        return LocalImageProvider.constructUri(path)
                    }
                }

                if (taskArray.indexOf(imageUrl) < 0) {
                    taskArray.add(imageUrl)
                    val mSubscription = Observable.create(Observable.OnSubscribe<String> { subscriber ->
                        try {
                            // 下载图片
                            val imgFile = File(
                                    ConfigUtil.getCachePath() + File.separator + FormatUtil.getFileNameFromUrl(
                                            imageUrl))

                            if (!imgFile.exists()) {
                                mOkHttpHelper.httpDownload(imageUrl, imgFile)
                            }
                            val path = imgFile.getAbsolutePath()
                            if (!TextUtils.isEmpty(path)) {
                                imageMap.put(imageUrl, path)
                                mImageCacheDao.queryBuilder()
                                        .where(ImageCacheDao.Properties.Url.eq(imageUrl))
                                        .buildDelete()
                                        .executeDeleteWithoutDetachingEntities()
                                val cache = ImageCache(null, imageUrl, path)
                                mImageCacheDao.insert(cache)
                            }
                            subscriber.onNext(path)
                            subscriber.onCompleted()
                        } catch (e: Exception) {
                            subscriber.onError(e)
                        }
                    })
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe({ s ->
                                if (!TextUtils.isEmpty(s)) {
                                    mContentView!!.loadUrl("javascript:replaceImage(\""
                                            + LocalImageProvider.constructUri(s)
                                            + "\","
                                            + index
                                            + ");")
                                }
                            }) {
                                mContentView!!.loadUrl("javascript:replaceImage(\""
                                        + LocalImageProvider.constructUri(imageUrl)
                                        + "\","
                                        + index
                                        + ");")
                            }
                    mCompositeSubscription.add(mSubscription)
                }
                return "file:///android_asset/hupu_thread_default.png"
            }
        }
    }
}
